#include "cminusf_builder.hpp"
#include "logging.hpp"
#define CONST_INT(num) \
    ConstantInt::get(num, module.get())

#define CONST_FP(num) \
    ConstantFP::get(num, module.get()) 

//global variables
Value *ret;               //遍历完一个节点后的返回值
std::vector<Type *> pType; //储存函数参数

// use these macros to get constant value
#define CONST_FP(num) \
    ConstantFP::get((float)num, module.get())
#define CONST_ZERO(type) \
    ConstantZero::get(var_type, module.get())


// You can define global variables here
// to store state

/*
 * use CMinusfBuilder::Scope to construct scopes
 * scope.enter: enter a new scope
 * scope.exit: exit current scope
 * scope.push: add a new binding to current scope
 * scope.find: find and return the value bound to the name
 */

//Program节点，需要接收一系列的定义，所以需要遍历declarations，调用accept函数识别是变量还是函数
//program -> declaration-list
void CminusfBuilder::visit(ASTProgram &node)
{

    for (auto decl : node.declarations)
    {
        decl->accept(*this);
    }
}
//num节点，只需判断这个数是整型还是浮点数
void CminusfBuilder::visit(ASTNum &node)
{
    if (node.type == TYPE_INT)
    {
        ret = CONST_INT(node.i_val);
    }
    else if (node.type == TYPE_FLOAT)
    {
        ret = CONST_FP(node.f_val);
    }
}
//变量声明，需要考虑局部变量还是全局变量，是否为数组
//var-declaration -> type-specifier ID ; ∣ type-specifier ID [INTEGER ]
void CminusfBuilder::visit(ASTVarDeclaration &node)
{
    //首先判断类型
    Type *declarationType;
    if(node.type==TYPE_INT){
        declarationType = Type::get_int32_type(module.get());
    }
    else if(node.type==TYPE_FLOAT){
        declarationType = Type::get_float_type(module.get());
    }
    //设定一个初始值
    auto initializer=ConstantZero::get(declarationType,module.get());
    if (!scope.in_global())//局部变量
    {
       if(node.num==nullptr)//不是数组
       {
           auto localVar=builder->create_alloca(declarationType);//分配空间
           scope.push(node.id,localVar);//加入作用域
       }
       else//数组
       {
           auto *arrayType=ArrayType::get(declarationType,node.num->i_val);//创建数组类型
           auto localArray=builder->create_alloca(arrayType);//分配空间
           scope.push(node.id,localArray);//加入作用域
       }
    }
    else //全局变量
    {
       if(node.num==nullptr)//不是数组
        {
            
            auto globalVar=GlobalVariable::create(node.id,module.get(),declarationType,false,initializer);
            scope.push(node.id,globalVar);
        }
        else//数组
        {
            auto *arrayType = ArrayType::get(declarationType,node.num->i_val);
            auto globalArray = GlobalVariable::create(node.id,module.get(),arrayType,false,initializer);
            scope.push(node.id,globalArray);
        }
    }
}
//函数声明，首先确定函数类型，然后接收参数,函数的主要内容访问交给另外一部分
//fun-declaration → type-specifier ID ( params ) compound-stmt
void CminusfBuilder::visit(ASTFunDeclaration &node)
{
    
    //先定义好各种类型，方便后面接收参数
    Type *TypeInt32 = Type::get_int32_type(module.get());
    Type *TypeFloat = Type::get_float_type(module.get());
    Type *TypeVoid = Type::get_void_type(module.get());
    Type *TYPEARRAY_INT_32 = PointerType::get_int32_ptr_type(module.get());
    Type *TYPEARRAY_FLOAT_32 = PointerType::get_float_ptr_type(module.get());
    Type *funType;
    int voidRet=0;
    if (node.type == TYPE_FLOAT)
        funType = TypeFloat;
    else if(node.type == TYPE_INT)
    {
        funType = TypeInt32;
    }
    else
    {
        funType = TypeVoid;
        voidRet=1;
    }
    //清空存储函数类型的vector
     while (!pType.empty())
    {
        pType.pop_back();
    }
    if (node.params.size() > 0) //参数列表非空
    {
        for (auto param : node.params)
        {
            param->accept(*this); //得到参数类型并分配空间
        }
        // 由函数类型得到函数
        auto fun = Function::create(FunctionType::get(funType, pType), node.id, module.get());
        scope.push(node.id, fun); //函数名放进作用域
        scope.enter();
        auto funBB = BasicBlock::create(module.get(), "entry", fun);
        builder->set_insert_point(funBB);
        //定义函数参数的vector
        std::vector<Value *> args;
        for (auto param : node.params) 
        {

            if (param->isarray)
            {
                if (param->type == TYPE_INT)
                {
                    auto pAlloca = builder->create_alloca(TYPEARRAY_INT_32); //在内存中分配空间
                    scope.push(param->id, pAlloca);
                }
                else if (param->type == TYPE_FLOAT)
                {
                    auto pAlloca = builder->create_alloca(TYPEARRAY_FLOAT_32);
                    scope.push(param->id, pAlloca);
                }
            }
            else if (param->type == TYPE_INT) //整型
            {
                auto pAlloca = builder->create_alloca(TypeInt32);
                scope.push(param->id, pAlloca);
            }
            else if (param->type == TYPE_FLOAT) //浮点型
            {
                auto pAlloca = builder->create_alloca(TypeFloat);
                scope.push(param->id, pAlloca);
            }
        }
        for (auto arg = fun->arg_begin(); arg != fun->arg_end(); arg++)
        {
            args.push_back(*arg);
        }
        int i = 0;
        //将参数store下来
        for (auto param : node.params)
        {
            auto pAlloca = scope.find(param->id);
            if (pAlloca == nullptr)
                exit(0);
            else
                builder->create_store(args[i++], pAlloca);
        }
    }
    else //参数列表为空
    {
        auto fun = Function::create(FunctionType::get(funType,pType), node.id, module.get());
        scope.push(node.id, fun); //函数名放进作用域
        scope.enter();
        auto funBB = BasicBlock::create(module.get(), "entry", fun);
        builder->set_insert_point(funBB);
    }
    node.compound_stmt->accept(*this);
    scope.exit();
}
//获取参数类型，先通过isarray判断是否为数组，再进行类型的判断
//param -> type-specifier ID | type-specifier ID []
void CminusfBuilder::visit(ASTParam &node)
{
    Type *TypeInt32 = Type::get_int32_type(module.get());
    Type *TypeFloat = Type::get_float_type(module.get());
    Type *TYPEARRAY_INT_32 = PointerType::get_int32_ptr_type(module.get());
    Type *TYPEARRAY_FLOAT_32 = PointerType::get_float_ptr_type(module.get());

    if (node.isarray) //数组
    {
        if (node.type == TYPE_INT)
        {
            pType.push_back(TYPEARRAY_INT_32);//传入pType
        }
        else if (node.type == TYPE_FLOAT)
        {
            pType.push_back(TYPEARRAY_FLOAT_32);
        }
    }
    else if (node.type == TYPE_INT) //整型
    {
        pType.push_back(TypeInt32);
    }
    else if (node.type == TYPE_FLOAT) //浮点型
    {
        pType.push_back(TypeFloat);
    }
}
//访问复合语句，一般是函数体，就需要分析局部变量的声明和一系列statement
// compound-stmt -> { local-declarations statement-list }
void CminusfBuilder::visit(ASTCompoundStmt &node)
{

    scope.enter();//进入作用域
    for (auto loc_decl : node.local_declarations)
    {
        loc_decl->accept(*this);//分析局部声明
    }
    for (auto stmt : node.statement_list)
    {
        stmt->accept(*this);//分析statement
    }
    scope.exit();
}
//分析表达式，只需判断是否为空，不为空就调用accept进行分析
//expression-stmt→expression ; ∣ ;
//expression→assign-expression ∣ simple-expression
void CminusfBuilder::visit(ASTExpressionStmt &node)
{
    if (node.expression != nullptr)
    {
        node.expression->accept(*this);
    }
}
//可能有else也可能没有，所以分两种情况讨论
//selection-stmt→ ​if ( expression ) statement∣ if ( expression ) statement else statement​
void CminusfBuilder::visit(ASTSelectionStmt &node)

{
    //先获取表达式的真值
    Type *TypeInt32 = Type::get_int32_type(module.get());
    node.expression->accept(*this);
    if (ret->get_type()->is_pointer_type())//如果返回值是个指针
        ret = builder->create_load(ret);
    if (ret->get_type()->is_float_type())//返回值为float型
        ret = builder->create_fcmp_ne(ret, CONST_FP(0));
    else if (ret->get_type() == TypeInt32)//返回值是int型
        ret = builder->create_icmp_ne(ret, CONST_INT(0));

    auto select = builder->get_insert_block()->get_parent();
    auto trueBB = BasicBlock::create(module.get(), "trueBB", select);
    int create= 0;//nextBB是否创建过
    BasicBlock* nextBB;
    //falseBB
    if (node.else_statement != nullptr) //有else
    {
        auto falseBB = BasicBlock::create(module.get(), "falseBB", select);
        builder->create_cond_br(ret, trueBB, falseBB);
        //falseBB
        builder->set_insert_point(falseBB);
        node.else_statement->accept(*this);
        if (builder->get_insert_block()->get_terminator() == nullptr)//没有返回或者跳转，直接跳到nextBB
        { 
            create= 1;
            nextBB = BasicBlock::create(module.get(), "nextBB", select);
            builder->create_br(nextBB);
        }
        //trueBB
        builder->set_insert_point(trueBB);
        node.if_statement->accept(*this);
        if (builder->get_insert_block()->get_terminator() == nullptr)//没有返回或者跳转，直接跳到nextBB
        { 
            if (create== 0)//创建nextBB
            {
                create= 1;
                nextBB = BasicBlock::create(module.get(), "nextBB", select);
            }
           
            builder->create_br(nextBB);
        }
        
        if (create== 1)
        {
            builder->set_insert_point(nextBB);
        }
    }
    else
    {
        
        nextBB = BasicBlock::create(module.get(), "nextBB", select);
        builder->create_cond_br(ret, trueBB, nextBB);
        //trueBB
        builder->set_insert_point(trueBB);
        node.if_statement->accept(*this);
        //nextBB
        if (builder->get_insert_block()->get_terminator() == nullptr)//没有返回或者跳转，直接跳到nextBB
        {
            builder->create_br(nextBB);
        }

  
        builder->set_insert_point(nextBB);
    }
}
//和selection类似，只有一种情况需要3个BasicBlock就可以了
//iteration-stmt→while ( expression ) statement
void CminusfBuilder::visit(ASTIterationStmt &node)
{
    Type *TypeInt32 = Type::get_int32_type(module.get());
    //selecttion
    auto select = builder->get_insert_block()->get_parent();
    auto cmpBB = BasicBlock::create(module.get(), "cmpBB", select);
    auto trueBB = BasicBlock::create(module.get(), "trueBB", select);
    auto nextBB = BasicBlock::create(module.get(), "nextBB", select);
    //cmpBB 
    builder->create_br(cmpBB);
    builder->set_insert_point(cmpBB);
    node.expression->accept(*this);
    //类型转换
    if (ret->get_type()->is_pointer_type())
        ret = builder->create_load(ret);
    if (ret->get_type()->is_float_type())
        ret = builder->create_fcmp_ne(ret, CONST_FP(0));
    else if (ret->get_type() == TypeInt32)
        ret = builder->create_icmp_ne(ret, CONST_INT(0));
    builder->create_cond_br(ret, trueBB, nextBB);

    //trueBB 
    builder->set_insert_point(trueBB);
    node.statement->accept(*this);
    if (builder->get_insert_block()->get_terminator() == nullptr)
        builder->create_br(cmpBB);

    //nextBB
    builder->set_insert_point(nextBB);
}
//返回需要返回正确类型的值，所以需要判断返回值的类型和规定的是否相等，不相等则要强制转换
//return-stmt→return ; ∣ return expression ;
void CminusfBuilder::visit(ASTReturnStmt &node)

{
    Type *TypeInt32 = Type::get_int32_type(module.get());
    Type *TypeInt1 = Type::get_int1_type(module.get());
    Type *TypeFloat = Type::get_float_type(module.get());
    auto returnType = builder->get_insert_block()->get_parent()->get_return_type();
    if (node.expression == nullptr)//返回void
    {
        builder->create_void_ret();
    }
    else
    {
        node.expression->accept(*this);
        //类型转换
        if (returnType->is_void_type())
        {
            builder->create_void_ret();
            return;
        }
        if (ret->get_type()->is_pointer_type())
            ret = builder->create_load(ret);
        if (returnType == TypeInt32)
        {
            if (ret->get_type() == TypeInt1)
                ret = builder->create_zext(ret, TypeInt32);
            else if (ret->get_type() == TypeFloat)
                ret = builder->create_fptosi(ret, TypeInt32);
        }
        if (returnType == TypeFloat)
        {
            if (ret->get_type()->is_integer_type())
                ret = builder->create_sitofp(ret, TypeFloat);
        }

        builder->create_ret(ret);
    }
}
//变量引用需要判断之前是否声明过，是否为数组
//var→ID ∣ ID [ expression]
void CminusfBuilder::visit(ASTVar &node)
{
    Type *FloatPtrType = Type::get_float_ptr_type(module.get());
    Type *Int32PtrType = Type::get_int32_ptr_type(module.get());
    Type *TypeInt32 = Type::get_int32_type(module.get());
    Type *TypeInt1 = Type::get_int1_type(module.get());
    auto select = builder->get_insert_block()->get_parent();
    auto var = scope.find(node.id);//从作用域中查找相应的变量
    if (node.expression != nullptr)//是数组
    {
        node.expression->accept(*this);
        Value *index= ret;
        //获取索引，索引必须是32为整型，如果不是则需要转换
        if (index->get_type()->is_pointer_type())
            index = builder->create_load(index);
        if (index->get_type() == TypeInt1)
            index = builder->create_zext(index, TypeInt32);
        else if (index->get_type()->is_float_type())
            index = builder->create_fptosi(index, TypeInt32);
        //索引小于0就报错
        auto errorBB = BasicBlock::create(module.get(), "", select);
        auto normalBB = BasicBlock::create(module.get(), "", select);
        auto nextBB = BasicBlock::create(module.get(), "", select);
        auto varflag = builder->create_icmp_ge(index, CONST_INT(0));
        builder->create_cond_br(varflag, normalBB, errorBB);

        //normalBB
        builder->set_insert_point(normalBB);
        if (var->get_type()->get_pointer_element_type()->is_pointer_type())
        {
            //是指针
            auto var_load = builder->create_load(var);
            var = builder->create_gep(var_load, {index});
        }
        else if (var->get_type()->get_pointer_element_type()->is_array_type())
        {
            //数组
            var = builder->create_gep(var, {CONST_INT(0), index});
        }
        else
        {
            printf("id is a float or int, but expression is not empty\n");
        }

        ret = var;
        builder->create_br(nextBB);

        //errorBB
        builder->set_insert_point(errorBB);
        Value * call_error = scope.find("neg_idx_except");
        builder->create_call(call_error, {});
        builder->create_br(nextBB);
        //nextBB
        builder->set_insert_point(nextBB);
    }
    else
    {
        if (var->get_type()->get_pointer_element_type()->is_array_type())//数组
        {
            var = builder->create_gep(var, {CONST_INT(0), CONST_INT(0)});
        }
        else if(var->get_type()->get_pointer_element_type()->is_pointer_type())//指针
        {
            var = builder->create_load(var);
        }
        ret = var;
    }
    
}
//赋值语句，主要考虑类型转换，转换成相同的类型再把值传给var
//assign-expression→var = expression
void CminusfBuilder::visit(ASTAssignExpression &node)
{
    Type *TypeInt32 = Type::get_int32_type(module.get());
    Type *TypeInt1 = Type::get_int1_type(module.get());
    Type *TypeFLOAT = Type::get_float_type(module.get());
    node.var.get()->accept(*this);
    Value *var = ret;
    node.expression.get()->accept(*this);
    if (var->get_type()->get_pointer_element_type()->is_float_type())
    {
        if (ret->get_type()->is_pointer_type())
            ret = builder->create_load(ret);
        if (ret->get_type()->is_integer_type())
            ret = builder->create_sitofp(ret, TypeFLOAT);
        builder->create_store(ret, var);
    }
    else
    {
        if (ret->get_type()->is_pointer_type())
            ret = builder->create_load(ret);
        if (ret->get_type() == TypeInt1)
            ret = builder->create_zext(ret, TypeInt32);
        else if (ret->get_type()->is_float_type())
            ret = builder->create_fptosi(ret, TypeInt32);
        builder->create_store(ret, var);
    }

}
//简单关系运算，直接分类
//simple-expression -> additive-expression relop additive- expression | additive-expression
//simple-expression -> additive-expression
//simple-expression -> additive-expression relop additive- expression
void CminusfBuilder::visit(ASTSimpleExpression &node)
{
    
    Type *TypeInt32 = Type::get_int32_type(module.get());
    Type *TypeFloat = Type::get_float_type(module.get());
    Type *TypeInt1 = Type::get_int1_type(module.get());
    //如果只有一个数据
    if (!node.additive_expression_r)
    {
        node.additive_expression_l->accept(*this);
    }
    else
    {
        //分别获取2个数据
        Value *addictiveLeft;
        Value *addictiveRight;
        Value *icmp;
        node.additive_expression_l->accept(*this);
        if (ret->get_type()->is_pointer_type())
            addictiveLeft = builder->create_load(ret);
        else
            addictiveLeft = ret;
        node.additive_expression_r->accept(*this);
        if (ret->get_type()->is_pointer_type())
            addictiveRight = builder->create_load(ret);
        else
            addictiveRight = ret;
        //是否存在浮点数的标志位
        int floatflag = 0;
        //如果两个数中至少有一个是浮点数
        if (addictiveLeft->get_type()->is_float_type())
        {
            floatflag = 1;
            if (addictiveRight->get_type()->is_integer_type())
                addictiveRight = builder->create_sitofp(addictiveRight, TypeFloat);
        }
        else
        {
            if (addictiveRight->get_type()->is_float_type())
            {
                floatflag = 1;
                addictiveLeft = builder->create_sitofp(addictiveLeft, TypeFloat);
            }
            else
            {
                floatflag = 0;
                if (addictiveLeft->get_type() == TypeInt1)
                    addictiveLeft = builder->create_zext(addictiveLeft, TypeInt32);
                if (addictiveRight->get_type() == TypeInt1)
                    addictiveRight = builder->create_zext(addictiveRight, TypeInt32);
            }
        }

        if (floatflag )
        {
            switch (node.op)
            {
            case OP_GE:
                icmp = builder->create_fcmp_ge(addictiveLeft, addictiveRight);
                break;
            case OP_GT:
                icmp = builder->create_fcmp_gt(addictiveLeft, addictiveRight);
                break;
            case OP_LE:
                icmp = builder->create_fcmp_le(addictiveLeft, addictiveRight);
                break;
            case OP_LT:
                icmp = builder->create_fcmp_lt(addictiveLeft, addictiveRight);
                break;
            case OP_EQ:
                icmp = builder->create_fcmp_eq(addictiveLeft, addictiveRight);
                break;
            case OP_NEQ:
                icmp = builder->create_fcmp_ne(addictiveLeft, addictiveRight);
                break;
            default:
                break;
            }
        }
        else
        {
            switch (node.op)
            {
            case OP_GE:
                icmp = builder->create_icmp_ge(addictiveLeft, addictiveRight);
                break;
            case OP_GT:
                icmp = builder->create_icmp_gt(addictiveLeft, addictiveRight);
                break;
            case OP_LE:
                icmp = builder->create_icmp_le(addictiveLeft, addictiveRight);
                break;
            case OP_LT:
                icmp = builder->create_icmp_lt(addictiveLeft, addictiveRight);
                break;
            case OP_EQ:
                icmp = builder->create_icmp_eq(addictiveLeft, addictiveRight);
                break;
            case OP_NEQ:
                icmp = builder->create_icmp_ne(addictiveLeft, addictiveRight);
                break;
            default:
                break;
            }
        }
        ret = icmp;
    }
}
//简单加减法，首先判断是否只有一个term，如果有两个项注意双方的类型
//additive-expression -> additive-expression addop term | term
void CminusfBuilder::visit(ASTAdditiveExpression &node)
{
    Type *TypeInt32 = Type::get_int32_type(module.get());
    Type *TypeInt1 = Type::get_int1_type(module.get());
    Type *TypeFloat = Type::get_float_type(module.get());
    Value *AdditiveExpression;
    Value *Term;
    Value *icmp;

    //如果只有term
    if (node.additive_expression == nullptr)
    {
        node.term->accept(*this);
    }
    else
    {
        //获取数据
        node.additive_expression->accept(*this);
        if (ret->get_type()->is_pointer_type())
            AdditiveExpression = builder->create_load(ret);
        else
            AdditiveExpression = ret;
        node.term->accept(*this);
        if (ret->get_type()->is_pointer_type())
            Term = builder->create_load(ret);
        else
            Term = ret;
        int floatflag = 0;//是否存在浮点数的标志位
        //如果是浮点数相加
        if (AdditiveExpression->get_type()->is_float_type())
        {
            floatflag = 1;
            if (Term->get_type()->is_integer_type())
                Term = builder->create_sitofp(Term, TypeFloat);
        }
        else
        {
            if (Term->get_type()->is_float_type())
            {
                floatflag = 1;
                AdditiveExpression = builder->create_sitofp(AdditiveExpression, TypeFloat);
            }
            else
            {
                floatflag = 0;
                if (AdditiveExpression->get_type() == TypeInt1)
                    AdditiveExpression = builder->create_zext(AdditiveExpression, TypeInt32);
                if (Term->get_type() == TypeInt1)
                    Term = builder->create_zext(Term, TypeInt32);
            }
        }

        if (floatflag == 1)
        {
            switch (node.op)
            {
            case  OP_PLUS:
                icmp = builder->create_fadd(AdditiveExpression, Term);
                break;
            
            case OP_MINUS:
                icmp = builder->create_fsub(AdditiveExpression, Term);
                break;
            }
        }
        else
        {
           switch (node.op)
            {
            case  OP_PLUS:
                icmp = builder->create_iadd(AdditiveExpression, Term);
                break;
            
            case OP_MINUS:
                icmp = builder->create_isub(AdditiveExpression, Term);
                break;
            }
        }
        ret = icmp;
    }
}
//简单的乘除运算，跟上一个差不多
//term -> term mulop factor | factor
void CminusfBuilder::visit(ASTTerm &node)
{
    
    Type *TypeInt32 = Type::get_int32_type(module.get());
    Type *TypeInt1 = Type::get_int1_type(module.get());
    Type *TypeFloat = Type::get_float_type(module.get());
    Value *Term;
    Value *Factor;
    Value *icmp;
    if (!node.term)//只有一个factor
    {
        node.factor->accept(*this);
    }
    else
    {
        node.term->accept(*this);
        if (ret->get_type()->is_pointer_type())
            Term = builder->create_load(ret);
        else
            Term = ret;
        node.factor->accept(*this);
        if (ret->get_type()->is_pointer_type())
            Factor = builder->create_load(ret);
        else
            Factor = ret;
        int floatflag = 0;
        if (Term->get_type()->is_float_type())
        {
            floatflag = 1;
            if (Factor->get_type()->is_integer_type())
                Factor = builder->create_sitofp(Factor, TypeFloat);
        }
        else
        {
            if (Factor->get_type()->is_float_type())
            {
                floatflag = 1;
                Term = builder->create_sitofp(Term, TypeFloat);
            }
            else
            {
                floatflag = 0;
                if (Factor->get_type() == TypeInt1)
                    Factor = builder->create_zext(Factor, TypeInt32);
                if (Term->get_type() == TypeInt1)
                    Term = builder->create_zext(Term, TypeInt32);
            }
        }

        if (floatflag == 1)
        {
           switch (node.op)
            {
            case  OP_MUL:
                icmp = builder->create_fmul(Term, Factor);
                break;
            
            case OP_MINUS:
                icmp = builder->create_fdiv(Term, Factor);
                break;
            }
        }
        else
        {
           switch (node.op)
            {
            case  OP_MUL:
                icmp = builder->create_imul(Term, Factor);
                break;
            
            case OP_MINUS:
                icmp = builder->create_isdiv(Term, Factor);
                break;
            }
        }
        ret = icmp;
    }
}

void CminusfBuilder::visit(ASTCall &node)
{
    auto function = scope.find(node.id);   
    auto fun = function->get_type();
    auto funType = static_cast<FunctionType *>(fun);
    int i = 0;
    std::vector<Value *> args;
    Type *TypeInt32 = Type::get_int32_type(module.get());
    Type *TypeFloat = Type::get_float_type(module.get());
    Type *Int32PtrType = Type::get_int32_ptr_type(module.get());
    Type *TypeInt1 = Type::get_int1_type(module.get());
    for (auto Args : node.args)
    {
        auto arg_type = funType->get_param_type(i);
        i++;
        Args->accept(*this);
        //ret为bool型需要转换成int32
        if (ret->get_type() == TypeInt1)
        {
            ret = builder->create_zext(ret, TypeInt32);
        }
        //argtype为整型，进行类型转换
        if (arg_type == TypeInt32)
        {
            if (ret->get_type()->is_pointer_type())
                ret = builder->create_load(ret);
            else if (ret->get_type() == TypeFloat)
                ret = builder->create_fptosi(ret, TypeInt32);
            args.push_back(ret);
        }
        //argtype为浮点数，进行类型转换
        else if (arg_type == TypeFloat)
        {
            if (ret->get_type()->is_pointer_type())
                ret = builder->create_load(ret);
            else if (ret->get_type() == TypeInt32)
                ret = builder->create_sitofp(ret, TypeFloat);
           args.push_back(ret);
        }
        //要求的参数为指针
        else
        {
            if (ret->get_type() == TypeInt32 || ret->get_type() == TypeFloat )
                return;
            args.push_back(ret);
        }
    }
    ret = builder->create_call(function,args);
}